package game;

import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;

import javax.swing.JOptionPane;

import card.Card;
import card.CardType;
import player.HP;
import player.Player;
import player.PlayerState;
import realCard.CardSha;
import realCard.CardShan;
import skill.SkillType;

public class PlayerOperation extends Thread implements ActionListener {

	/**游戏主界面*/
	GameJFrame gameJFrame;

	/**是否能走*/
	boolean isRun = true;

	/**倒计时*/
	int time;

	/**判断是否要重置回合:是否要加牌*/
	boolean addFlag = false;

	public PlayerOperation(GameJFrame m, int time) {
		this.gameJFrame = m;
		this.time = time;
	}

	@Override
	public void run() {
		this.sleep(4);
		while (time > -1 && isRun) {
			gameJFrame.getTime()[0].setText("倒计时:" + time--);
			sleep(1);
		}
		for (Card card : gameJFrame.playerList.get(0)) {
			// 可被点击
			card.setCanClick(true);
		}
		turnOn(false);
		while (true) {
			//玩家自己的回合
			this.sleep(2);
			if (gameJFrame.getTurn() == 0) {
				
				gameJFrame.getTime()[1].setVisible(false);
				System.out.println("你的回合");
				Player player = gameJFrame.getPlayersArr().get(0);
				ArrayList<Card> handsCard = player.getHandsCard();
				//如果选择的角色技能可以突破一些限制，就发动
				if(player.getSelectedRole().getSkill().getType() == SkillType.PUSH_THE_LIMITS) {
					player.getSelectedRole().getSkill().effect();
				}
				//一些解除限制武器牌，也可以发动
				for(int i= 0; i < 4; i++) {
					if(player.getEquipment()[i]!= null && player.getEquipment()[i].getEffect() == PlayerState.PUSH_THE_LIMIT) {
						player.getEquipment()[i].effect(player);
					}
				}
				// 被击状态：要做出响应
				if (player.getState() == PlayerState.BEHURT) {
					gameJFrame.getTip().setText("请出“闪”规避伤害");
					gameJFrame.getTip().setVisible(true);
					boolean hasShanFlag = false;
					// 所有非闪牌不可点击
					for (Card card : handsCard) {
						if (card.getClass() != CardShan.class) {
							card.setCanClick(false);
						}
						if(card.getClass() == CardShan.class) {
							hasShanFlag = true;
						}
					}
					if(!hasShanFlag) {
						gameJFrame.getPlayerButton()[0].setEnabled(false);
					}else{
						gameJFrame.getPlayerButton()[0].setEnabled(true);
					}
					turnOn(true);
					timeWait(10, 0);
					turnOn(false);
					gameJFrame.getPlayerButton()[0].setEnabled(true);
					gameJFrame.getTip().setVisible(false);
					// 恢复所有手牌的点击权
					for (Card card : handsCard) {
						if (card.getClass() != CardShan.class) {
							card.setCanClick(true);
						}
					}
					// 在出牌阶段未能改变自己的状态：则受伤，进入已受伤的状态
					if (player.getState() == PlayerState.BEHURT) {
						player.setState(PlayerState.BEHURTED);
						player.reduceHP();
						try {
							// 图形效果
							player.getSelectedRole().beHurt();
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						player.getHP().rePaintHP();
						gameJFrame.getRecordArea().append(player.getSelectedRole().getName() + "受到伤害，剩余生命为："
								+ player.getHP().getActualHP() + "\n");
					}
					//技能判断：是否受伤
					if(player.getSelectedRole().getSkill().getType() == SkillType.WHEN_HURT) {
						if(player.getState() == PlayerState.BEHURTED) {
							gameJFrame.getTip().setText("是否发动" + player.getSelectedRole().getSkill().getName() + "？");
							gameJFrame.getTip().setVisible(true);
							turnOnSkill(true);
							timeWait(10, 0);
							turnOnSkill(false);
							gameJFrame.getTip().setVisible(false);
						}
					}
					player.setState(PlayerState.NONE);
					gameJFrame.setTurn((gameJFrame.getTurn() + 1) % 2);
					continue;

				}
				// 我的回合：发牌
				else if (player.isCanGetCard()) {
					player.setCanGetCard(false);
					ArrayList<Card> addCardList = new ArrayList<>();
					/* 判断：如果牌堆没牌了，那就把弃牌堆富裕牌堆 */
					if (gameJFrame.getCardList().size() < 2) {
						int remain = gameJFrame.getCardList().size();
						for (int i = 0; i < gameJFrame.getCardList().size(); i++) {
							Card addCard = gameJFrame.getCardList().get(i);
							addCard.setCanClick(true);
							addCardList.add(addCard);
						}
						// 更新牌堆
						deckUpdate(gameJFrame.getCardList(), gameJFrame.getFoldPile());
						System.out.println("更新完的牌堆的长度为：" + gameJFrame.getCardList().size());
						for (int i = 0; i < 2 - remain; i++) {
							Card addCard = gameJFrame.getCardList().get(i);
							addCard.setCanClick(true);
							addCardList.add(addCard);
						}
						for (int i = 0; i < 2; i++) {
							Card addCard = addCardList.get(i);
							Point to = null;
							if (player.getHandsCard().size() != 0) {
									to = new Point(gameJFrame.playerList.get(0).get(gameJFrame.playerList.get(0).size() - 1).getX() + i * 90, 530);
							}else {
								to = new Point(110, 530);
							}
							Common.move(addCard, addCard.getLocation(),new Point(250 + gameJFrame.playerList.get(0).size() * 90 + i * 90, 530));
							addCard.turnFront();
						}
					} else {
						for (int i = 0; i < 2; i++) {
							Card addCard = gameJFrame.getCardList().get(i);
							addCard.setCanClick(true);
							Point to = null;
							if (player.getHandsCard().size() != 0) {
								to = new Point(
										gameJFrame.playerList.get(0).get(gameJFrame.playerList.get(0).size() - 1).getX()
												+ i * 90,
										530);
							} else {
								to = new Point(110, 530);
							}
							Common.move(addCard, addCard.getLocation(),
									new Point(250 + gameJFrame.playerList.get(0).size() * 90 + i * 90, 530));
							addCard.turnFront();
							addCardList.add(addCard);
						}
					}
					gameJFrame.getCardList().removeAll(addCardList);
					gameJFrame.playerList.get(gameJFrame.getTurn()).addAll(addCardList);
					Common.rePositon(gameJFrame, gameJFrame.playerList.get(gameJFrame.getTurn()), gameJFrame.getTurn());
				}
				turnOn(true);
				timeWait(30, 0);
				turnOn(false);
				if (gameJFrame.getTurn() != 0) {
					addFlag = false;
					continue;
				}
				if (gameJFrame.getPlayersArr().get(0).getHandsCard().size() > gameJFrame.getPlayersArr().get(0).getHP()
						.getActualHP()) {
					turnOnMultipleClicks(gameJFrame.playerList.get(gameJFrame.getTurn()), true);
					gameJFrame.getTip()
							.setText("请丢弃 " + (player.getHandsCard().size() - player.getHP().getActualHP()) + " 张牌");
					gameJFrame.getTip().setVisible(true);
					turnOnFold(true);
					timeWait(15, 0);
					turnOnFold(false);
					gameJFrame.getTip().setVisible(false);
					turnOnMultipleClicks(gameJFrame.playerList.get(gameJFrame.getTurn()), false);
				}
				player.setMyRound(false);
				gameJFrame.setTurn((gameJFrame.getTurn() + 1) % 2);
				gameJFrame.getPlayersArr().get(gameJFrame.getTurn()).reflesh();
				gameJFrame.getPlayersArr().get(gameJFrame.getTurn()).setCanGetCard(true);
				gameJFrame.getPlayersArr().get(gameJFrame.getTurn()).setMyRound(true);
				if (win()) {
					break;
				}
			}
			/* 敌方的回合 */
			if (gameJFrame.getTurn() == 1) {
				Player player1 = gameJFrame.getPlayersArr().get(1);
				if(player1.getSelectedRole().getSkill().getType() == SkillType.PUSH_THE_LIMITS) {
					player1.getSelectedRole().getSkill().effect();
				}
				/*一些解除限制武器牌，也可以发动*/
				for(int i= 0; i < 4; i++) {
					if(player1.getEquipment()[i]!= null && player1.getEquipment()[i].getEffect() == PlayerState.PUSH_THE_LIMIT) {
						player1.getEquipment()[i].effect(player1);
					}
				}

				/* 如果是被伤害：并非自己的回合，而是判定是否要出闪 */
				if (player1.getState() == PlayerState.BEHURT) {
					System.out.println("computer为被伤状态，进入闪环节");
					computer_dealBeHurt(1);

				} else {
					// 正常回合，直接发牌
					if (player1.isCanGetCard()) {
						player1.setCanGetCard(false);
						System.out.println("给敌方发牌");
						System.out.println("正常阶段: 现在玩家的手牌数是：" + gameJFrame.playerList.get(gameJFrame.getTurn()).size()
								+ "现在玩家的状态是" + gameJFrame.getPlayersArr().get(gameJFrame.getTurn()).getState());
						ArrayList<Card> addCardList = new ArrayList<>();
						
						if (gameJFrame.getCardList().size() < 2) {
							System.out.println("牌堆小于2 ！！！   长度为：" + gameJFrame.getCardList().size());
							int remain = gameJFrame.getCardList().size();
							for (int i = 0; i < gameJFrame.getCardList().size(); i++) {
								Card addCard = gameJFrame.getCardList().get(i);
								addCard.setCanClick(false);
								addCardList.add(addCard);
							}
							deckUpdate(gameJFrame.getCardList(), gameJFrame.getFoldPile());
							System.out.println("更新完的牌堆的长度为：" + gameJFrame.getCardList().size());
							for (int i = 0; i < 2 - remain; i++) {
								Card addCard = gameJFrame.getCardList().get(i);
								addCard.setCanClick(false);
								addCardList.add(addCard);
							}
							for (int i = 0; i < 2; i++) {
								Card addCard = addCardList.get(i);
								Common.move(addCard, addCard.getLocation(), new Point(300, 50));
							}
						}else {
							for (int i = 0; i < 2; i++) {
								Card addCard = gameJFrame.getCardList().get(i);
								addCard.setCanClick(false);
								Common.move(addCard, addCard.getLocation(), new Point(300, 50));
								addCardList.add(addCard);
							}
						}
						gameJFrame.getCardList().removeAll(addCardList);
						gameJFrame.playerList.get(gameJFrame.getTurn()).addAll(addCardList);
					}
					computer_dealTreatCard(1);
					if (computerDealHurtCard(gameJFrame.getTurn())) {
						gameJFrame.setTurn((gameJFrame.getTurn() + 1) % 2);
						addFlag = false;
						continue;
					}
					computer1();
				}
				gameJFrame.setTurn((gameJFrame.getTurn() + 1) % 2);
				if (win()) {
					break;
				}
			}
		}
	}
	/**定义一个方法用来暂停N秒
	   参数为等待的时间
	   因为线程中的sleep方法有异常，直接调用影响阅读*/
	public void sleep(int i) {
		try {
			Thread.sleep(i * 1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	/**出牌和结束的开关*/
	public void turnOn(boolean flag) {
		gameJFrame.getPlayerButton()[0].setVisible(flag);
		gameJFrame.getPlayerButton()[1].setVisible(flag);
		gameJFrame.getTime()[0].setVisible(flag);
		gameJFrame.repaint();
	}

	/**弃牌的开关*/
	public void turnOnFold(boolean flag) {
		gameJFrame.getPlayerButton()[2].setVisible(flag);
		gameJFrame.repaint();
	}
	
	/**技能触发的开关*/
	public void turnOnSkill(boolean flag) {
		gameJFrame.getPlayerButton()[3].setVisible(flag);
		gameJFrame.getPlayerButton()[4].setVisible(flag);
		gameJFrame.getTime()[0].setVisible(flag);
		gameJFrame.repaint();
	}

	/**让牌能否被多张同时点击的开关*/
	public void turnOnMultipleClicks(ArrayList<Card> handsCard, boolean flag) {
		for (Card card : handsCard) {
			card.setMultipleClicks(flag);
		}
	}

	public void computer1() {
		timeWait(2, 1);
		ShowCard(1);
	}

	public void computer_dealBeHurt(int player) {
		/* 找到电脑代理的对应玩家、手牌、生命和要出的牌 */
		timeWait(4, 1);
		Player computerPlayer = gameJFrame.getPlayersArr().get(player);
		ArrayList<Card> computerHandsCard = gameJFrame.playerList.get(player);
		HP computerHP = computerPlayer.getHP();
		Card removeCard = null;
		for (Card card : computerHandsCard) {
			if (card.getClass() == CardShan.class) {
				removeCard = card;
				break;
			}
		}
		/* 如果没有闪：扣血 */
		if (removeCard == null) {
			System.out.println("扣血");
			computerPlayer.reduceHP();
			try {
				// 图形效果
				computerPlayer.getSelectedRole().beHurt();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			computerHP = computerPlayer.getHP();
			/* 血槽更新 */
			computerHP.rePaintHP();
			gameJFrame.getRecordArea().append(computerPlayer.getSelectedRole().getName() + " 生命减少，剩余生命为："
					+ computerPlayer.getHP().getActualHP() + "\n");
			gameJFrame.getTime()[1].setText("不出");
			gameJFrame.getTime()[1].setVisible(true);
		} else {
			System.out.println("出闪");
			removeCard.turnFront();
			gameJFrame.getContainer().setComponentZOrder(removeCard, 0);
			Common.moveHandsCard(removeCard, player, computerHandsCard);
			gameJFrame.playerList.get(player).remove(removeCard);
			gameJFrame.getRecordArea().append(computerPlayer.getSelectedRole().getName() + "回应了闪\n");
		}
		System.out.println("computer变为无的状态");
		// 变成未被伤害的状态
		computerPlayer.setState(PlayerState.NONE);
	}

	public boolean computerDealHurtCard(int player) {
		boolean flag = false;

		Card removeCard = null;
		ArrayList<Card> handsCard = gameJFrame.getPlayersArr().get(player).getHandsCard();
		for (Card card : gameJFrame.playerList.get(player)) {
			if (card.getEffect() == PlayerState.BEHURT) {
				removeCard = card;
				break;
			}
		}
		gameJFrame.getTime()[player].setVisible(true);
		timeWait(2, player);
		if (removeCard == null)
			return false;
		if ( (removeCard.getClass() == CardSha.class) && (! gameJFrame.getPlayersArr().get(player).isSendCardShaFlag())) {
			gameJFrame.getContainer().setComponentZOrder(removeCard, 0);
			removeCard.turnFront();
			Common.moveHandsCard(removeCard, player, handsCard);
			gameJFrame.getFoldPile().add(removeCard);
			gameJFrame.getPlayersArr().get(player).setSendCardShaFlag(true);
			gameJFrame.getPlayersArr().get(0).setState(PlayerState.BEHURT);
			gameJFrame.getRecordArea().append(gameJFrame.getPlayersArr().get(player).getSelectedRole().getName() + " 对 "
					+ gameJFrame.getPlayersArr().get(0).getSelectedRole().getName() + " 发动了 杀\n");
			flag = true;
		}else if(removeCard.getType() == CardType.TIP) {
			gameJFrame.getContainer().setComponentZOrder(removeCard, 0);
			removeCard.turnFront();
			Common.moveHandsCard(removeCard, player, handsCard);
			gameJFrame.getFoldPile().add(removeCard);
			removeCard.effect(gameJFrame.getPlayersArr().get(player));
			gameJFrame.getRecordArea().append(gameJFrame.getPlayersArr().get(player).getSelectedRole().getName() + " 发动了 "
					+ removeCard.getName());
			flag = true;
		}

		return flag;
	}

	public void computer_dealTreatCard(int player) {
		ArrayList<Card> cardsWillBeUsed = new ArrayList<>();
		Player computerPlayer = gameJFrame.getPlayersArr().get(player);
		int needNum = computerPlayer.getHP().getMaximumHP() - computerPlayer.getHP().getActualHP();
		int canUsedSize = 0;
		if(needNum == 0) {
			return;
		}
		for(Card card : computerPlayer.getHandsCard()) {
			if(card.getEffect() == PlayerState.GET_TREATED) {
				cardsWillBeUsed.add(card);
			}
		}
		if(needNum > cardsWillBeUsed.size()) {
			canUsedSize = cardsWillBeUsed.size();
		}else {
			canUsedSize = needNum;
		}
		for(int i = 0; i < canUsedSize; i++) {
			cardsWillBeUsed.get(i).effect(computerPlayer);
			cardsWillBeUsed.get(i).turnFront();
			Common.moveHandsCard(cardsWillBeUsed.get(i), player, computerPlayer.getHandsCard());
			gameJFrame.getFoldPile().add(cardsWillBeUsed.get(i));
			gameJFrame.getRecordArea().append(
					computerPlayer.getSelectedRole().getName() + " 对 " + computerPlayer.getSelectedRole().getName()
							+ " 使用了 " + cardsWillBeUsed.get(i).getName() + "，目前"
							+ computerPlayer.getSelectedRole().getName() + "的生命为："
							+ computerPlayer.getHP().getActualHP() + "\n");
		}
		
	}

	public void ShowCard(int player) {

		Card removeCard = null;

		gameJFrame.getTime()[player].setVisible(true);
		if (removeCard == null) {
			if (gameJFrame.getPlayersArr().get(player).getHandsCard().size() > gameJFrame.getPlayersArr().get(player).getHP()
					.getActualHP())
				gameJFrame.getTime()[player].setText("弃牌");
			for (int i = 0; i < gameJFrame.getPlayersArr().get(player).getHandsCard().size()
					- gameJFrame.getPlayersArr().get(player).getHP().getActualHP(); i++) {
				removeCard = gameJFrame.getPlayersArr().get(player).getHandsCard().get(i);
				gameJFrame.getContainer().setComponentZOrder(removeCard, 0);
				removeCard.turnFront();
				Common.moveHandsCard(removeCard, player, gameJFrame.getPlayersArr().get(player).getHandsCard());
			}
			int nextPlayer = (player + 1) % 2;
			gameJFrame.getPlayersArr().get(nextPlayer).reflesh();
			gameJFrame.getPlayersArr().get(nextPlayer).setMyRound(true);
			gameJFrame.getPlayersArr().get(nextPlayer).setCanGetCard(true);
			/* 关掉text */
			sleep(2);
			gameJFrame.getTime()[player].setVisible(false);
		}
	}

	public void timeWait(int n, int player) {
		System.out.println("现在player是: " + player);
		if (player == 0) {
			// 自己的回合
			int i = n;
			while (gameJFrame.nextPlayer == false && i >= 0) {
				gameJFrame.getTime()[player].setText("倒计时:" + i);
				gameJFrame.getTime()[player].setVisible(true);
				sleep(1);
				i--;
			}
			if (i == -1 && player == 0) {

				if (gameJFrame.getPlayerButton()[2].isVisible()) {// 在弃牌阶段
					ArrayList<Card> handsCard = gameJFrame.getPlayersArr().get(0).getHandsCard();
					ArrayList<Card> removeCardList = new ArrayList<>();
					for (int j = 0; j < handsCard.size() - gameJFrame.getPlayersArr().get(0).getHP().getActualHP(); j++) {
						removeCardList.add(gameJFrame.getPlayersArr().get(0).getHandsCard().get(j));
					}
					for (Card removeCard : removeCardList) {
						Runnable moveTask = new MoveCartoon(removeCard, new Point(150, 250));
						EventQueue.invokeLater(new Runnable() {

							@Override
							public void run() {
								// TODO Auto-generated method stub
								Thread move = new Thread(moveTask);
								move.start();
							}
						});
					}
					handsCard.removeAll(removeCardList);
					Common.rePositon(gameJFrame, handsCard, 0);
				}
			}
			gameJFrame.nextPlayer = false;
		} else {
			// 对手的回合
			for (int i = n; i >= 0; i--) {
				sleep(1);
				gameJFrame.getTime()[player].setText("倒计时:" + i);
				gameJFrame.getTime()[player].setVisible(true);
			}
		}
		gameJFrame.getTime()[player].setVisible(false);
		System.out.println("关闭玩家" + player + "时间文本,现在该玩家的时间显示是：" + gameJFrame.getTime()[player].isVisible());
		gameJFrame.repaint();// 个人补充
	}

	/**判断你是否胜利*/
	public boolean win() {
		for (int i = 0; i < 2; i++) {
			if (gameJFrame.getPlayersArr().get(i).getHP().getActualHP() == 0) { // 有玩家生命为0
				String s;
				if (i == 1) {
					s = "恭喜你，胜利了!";
				} else {
					s = "恭喜电脑" + i + ",赢了! 你就是逊哦！";
				}
				JOptionPane.showMessageDialog(gameJFrame, s);
				return true;
			}
		}
		return false;
	}

	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == gameJFrame.getPlayersArr().get(0).getHandsCard()) {
			System.out.println("玩家0的手牌变动");
		} else if (e.getSource() == gameJFrame.getPlayersArr().get(1).getHandsCard()) {
			System.out.println("玩家1的手牌变动");
		} else {
			System.out.println("无响应");
		}
	}

	/**牌堆更新*/
	public void deckUpdate(ArrayList<Card> deck, ArrayList<Card> foldPile) {
		Collections.shuffle(foldPile);
		for (Card card : foldPile) {
			card.setVisible(true);
			card.turnRear();
			card.setCanClick(false);
			card.setClicked(false);
			gameJFrame.getContainer().setComponentZOrder(card, 0);
			Common.moveCard(card, new Point(30, 200));
			deck.add(card);
		}
		foldPile.clear();
	}

}
